package com.googlecode.ascrblr.api.radio.xspf;

import java.io.UnsupportedEncodingException;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLDecoder;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.logging.Logger;

import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;

public class Track {
	/** 
	 * Logger instance. 
	 */
	public static final Logger logger = Logger.getLogger(Track.class.getName());
	
	/** ID */
	private String id;
	
	/** Title */
	private String title;
	
	/** Creator */
	private String creator;
	
	/** Album artwork */
	private String image;
	
	/** Album title */
	private String album;
	
	/** Track duration in ms */
	private Long duration;
	
	/** Track authCode */
	private String authCode;
	
	/** Album ID */
	private String albumId;
	
	/** Artist ID */
	private String artistId;
	
	/** Sponsor */
	private String sponsored;

	/** Track locations */
	private List<URL> locations;
	
	/** Links */
	private Map<String,URL> links;
	
	/**
	 * Creates a <code>Track</code> instance out of a <track> element
	 * 
	 * @param node track element from playlist
	 */
	public Track(Node node) {
		
		parse(node);
		
	}
	
	/**
	 * Adds a location
	 * @param location
	 */
	private void addLocation(URL location) {
		if(locations == null) {
			locations = new ArrayList<URL>();
		}
		locations.add(location);
	}
	
	/**
	 * Adds a link
	 * 
	 * @param rel link relation. <br/>
	 * 				Possible values are 
	 * 				<li>http://www.last.fm/artistpage
	 * 				<li>http://www.last.fm/albumpage
     *   			<li>http://www.last.fm/trackpage
     *   			<li>http://www.last.fm/buyTrackURL
     *   			<li>http://www.last.fm/buyAlbumURL
     *   			<li>http://www.last.fm/freeTrackURL
	 * @param url link URL
	 */
	private void addLink(String rel, URL url) {
		if(links == null) {
			links = new HashMap<String,URL>();
		}
		links.put(rel, url);
	}
	
	/**
	 * Parses <track> node
	 * 
	 * @param node track node from playlist
	 */
	private void parse(Node node) {

		node = node.getFirstChild().getNextSibling();
		
		do {
			
        	String tagName = node.getNodeName();
        	String value = node.getTextContent();
        	
        	if("id".equals(tagName)) {
        		id = value;
			}else if("title".equals(tagName)) {
        		try {
        			title = value;
        			title = URLDecoder.decode(title, "UTF-8");
        		}catch(UnsupportedEncodingException e){
        			//ignore and leave undecoded
        		}
        	}else if("creator".equals(tagName)){
        		creator = value;
        	}else if("album".equals(tagName)) {
        		album = value;
        	}else if("duration".equals(tagName)) {
        		duration = Long.valueOf(value);
        		//it seems there are some tracks with 0 length :-/
        		if(duration == 0) {
        			duration = 60000L;
        		}
        	}else if("location".equals(tagName)) {
        		try {
        			addLocation(new URL(value));
        		}catch(MalformedURLException e) {
        			logger.fine(e.getMessage());
        		}
        	}else if("link".equals(tagName)) {
        		try {
        			NamedNodeMap attr = node.getAttributes();
        			Node rel = attr.getNamedItem("rel");
        			if(rel != null) {
        				addLink(rel.getTextContent(),new URL(value));
        			}
        		}catch(MalformedURLException e) {
        			//Just log
        			logger.fine(e.getMessage());
        		}
        	}else if("lastfm:trackauth".equals(tagName)) {
        		authCode = value;
        	}else if("lastfm:albumId".equals(tagName)) {
        		albumId = value;
        	}else if("lastfm:artistId".equals(tagName)) {
        		artistId = value;
        	}else if("lastfm:sponsored".equals(tagName)) {
        		sponsored = value;
        	}
	
        	node = node.getNextSibling().getNextSibling();
        	
    	}while(node != null);
		
	}
	
	/**
	 * Gets track ID
	 * 
	 * @return
	 */
	public String getId() {
		return id;
	}

	/**
	 * Get track title
	 * 
	 * @return
	 */
	public String getTitle() {
		return title;
	}

	/** 
	 * Get track creator
	 * 
	 * @return
	 */
	public String getCreator() {
		return creator;
	}

	/**
	 * Get album artwork
	 * 
	 * @return
	 */
	public String getImage() {
		return image;
	}

	/**
	 * Get album title
	 * 
	 * @return
	 */
	public String getAlbum() {
		return album;
	}

	/**
	 * Get track duration in milliseconds
	 * 
	 * @return
	 */
	public Long getDuration() {
		return duration;
	}

	/**
	 * Get AuthCode
	 * @return
	 */
	public String getAuthCode() {
		return authCode;
	}

	/**
	 * Get album ID
	 * 
	 * @return
	 */
	public String getAlbumId() {
		return albumId;
	}

	/**
	 * Get artist ID
	 * 
	 * @return
	 */
	public String getArtistId() {
		return artistId;
	}

	/**
	 * Get sponsor
	 * 
	 * @return
	 */
	public String getSponsored() {
		return sponsored;
	}

	/**
	 * Get track locations
	 * 
	 * @return
	 */
	public List<URL> getLocations() {
		return locations;
	}

	/**
	 * Get a <code>Map</code> of related links.
	 * 
	 * @return <code>Map</code> of related links. Possible values are 
	 * 				<li>http://www.last.fm/artistpage
	 * 				<li>http://www.last.fm/albumpage
     *   			<li>http://www.last.fm/trackpage
     *   			<li>http://www.last.fm/buyTrackURL
     *   			<li>http://www.last.fm/buyAlbumURL
     *   			<li>http://www.last.fm/freeTrackURL
	 */
	public Map<String, URL> getLinks() {
		return links;
	}


}
